#include "UserPortRS232.h"
#include <string.h>
#include <stdio.h>
#include <cbm.h>
#include <peekpoke.h>
#include <conio.h>
#include <errno.h>
#include <time.h>

#include "up.h"
#include "Global.h"

/*
char readChar(char lfn);
void writeChar(char lfn, char byte);
*/
#define pGET_BUF (*(unsigned char* *)0xF7)
#define pSEND_BUF (*(unsigned char* *)0xF9)

char openRS232(char lfn, baud_t baud)
{
	static int r;
	static int rate;
	static char control, command;
	static char low, high;
	static char file[5];	

#ifdef __C64__
	static unsigned char get_buf[256];
	static unsigned char send_buf[256];

	pGET_BUF = get_buf;
	pSEND_BUF = send_buf;
#endif


	control = 0; 
	command = 2;
	
	init();

	switch(baud)
	{
	case BAUD_300:
		//rate = 1022727/300/2-100;
		control = 6;
		break;

	case BAUD_1200:
		//rate = 1022727/1200/2-100;
		control = 8;
		break;

	case BAUD_2400:
		//rate = 1022727/2400/2-100;
		control = 10;
		break;
	}

	//low = rate % 256;
	//high = rate / 256;

	//sprintf(file, "%c%c%c%c", control, command, low, high);
	sprintf(file, "%c%c\0", control, command);

	r=cbm_open(lfn, 2, 3, file);

	POKE(0xDD03, 0x06);
	//gotoxy(0, 0); cprintf("_oserror: %u", _oserror); cgetc();

	return r;
}

void enableRS232(void)
{
	inable();
}

char readByteRS232(void)
{
	char byte;
	inable();
	__asm__("LDA #$00");
	byte = rsget();
	return byte;
}

void __fastcall__ writeByteRS232(char byte)
{
	__asm__("LDA $EA");
	__asm__("PHA");
	POKE(0xEA, byte);
	__asm__("LDA $EA");
	rsout();
	__asm__("PLA");
	__asm__("STA $EA");
}

void closeRS232(char lfn)
{
	disable();
	cbm_close(lfn);
}

char readStatus()
{
	return cbm_k_readst();
}

void setBaudRS232(baud_t oldBaud, baud_t newBaud)
{
	static char buffer[9];
	unsigned char rate, i;

	switch(newBaud)
	{
	case 0: rate = 3; break;
	case 1: rate = 5; break;
	case 2: rate = 6; break;
	}

	sprintf(buffer, "ats37=%u\n", rate);

	openRS232(2, oldBaud);
	
	enableRS232();
	for(i = 0; i < 8; ++i)
	{
		writeByteRS232(buffer[i]);
	}

	closeRS232(2);

	return;
}

#ifdef __NODCD__
bool _dcd = false;
#endif

bool readDCD(void)
{
#ifndef __NODCD__
	char r = PEEK(0xDD01) & 0x10;
	//printf("%02X", r);
	return r == 0x10;
#else
	return _dcd;
#endif
}

bool readCTS(void)
{
	return PEEK(0xDD01) & 64 == 64;
}
bool readRI(void)
{
	return PEEK(0xDD01) & 8 == 8;
}
void setRTS(bool set)
{
	if(set)
	{
		POKE(0xDD01, PEEK(0xDD01) | 2);
	}
	else
	{
		POKE(0xDD01, PEEK(0xDD01) & 253);
	}
}
void setDTR(bool set)
{
	if(set)
	{
		POKE(0xDD01, PEEK(0xDD01) | 4);
	}
	else
	{
		POKE(0xDD01, PEEK(0xDD01) & 251);
	}
}

void hangUpCall(void)
{
	time_t now = time(NULL);

	if(readDCD())
	{
		setRTS(true);
		writeByteRS232(0);
		writeByteRS232(0);
		writeByteRS232(0);
		while(time(NULL) == now);
		writeByteRS232('a');
		writeByteRS232('t');
		writeByteRS232('h');
		writeByteRS232('\n');
		now=time(NULL);
		while(now==time(NULL));
		readByteRS232();
		setRTS(false);
		setDTR(false);
		_connectState = readDCD() ? CS_CONNECTED : CS_DISCONNECTED;
	}
}

void clearReadBuffer(void)
{
	while(readByteRS232() != 0);
}